<template>
  <div v-if="dialogVisible" class="">
    <a-modal
      v-model:visible="dialogVisible"
      :title="dialogTitle"
      :ok-loading="btnLoading"
      :modal-style="modalStyle"
      :body-style="bodyStyle"
      :mask-closable="false"
      @cancel="dialogCancel"
      @before-ok="dialogBeforeOk"
    >
      <a-form ref="formRef" :model="formModel">
        <a-row :gutter="16">
          <a-col :span="24">
            <a-form-item field="parent_id" label="上一级" label-col-flex="100px">
              <a-cascader
                v-model="formModel.parent_id"
                :options="treeDatas"
                :field-names="{ value: 'id', label: 'name' }"
                placeholder="一级菜单"
                check-strictly
                allow-search
                allow-clear
                style="width: 60%"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              field="name"
              label="名称"
              required
              :validate-trigger="['change','input']"
              :rules="[
                {
                  required: true,
                  message: '名称不能为空',
                },
              ]"
              label-col-flex="100px"
            >
              <a-input v-model="formModel.name" placeholder="请输入名称"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              field="app"
              label="应用"
              required
              :validate-trigger="['change','input']"
              :rules="[
                {
                  required: true,
                  message: '应用不能为空',
                },
              ]"
              label-col-flex="100px"
            >
              <a-input v-model="formModel.app" placeholder="区分大小写"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              field="controller"
              label="控制器"
              required
              :validate-trigger="['change','input']"
              :rules="[
                {
                  required: true,
                  message: '控制器不能为空',
                },
              ]"
              label-col-flex="100px"
            >
              <a-input v-model="formModel.controller" placeholder="区分大小写"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="action" label="操作" label-col-flex="100px">
              <a-input v-model="formModel.action" placeholder="区分大小写"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="route" label="前端路由" label-col-flex="100px">
              <a-input v-model="formModel.route" placeholder="区分大小写"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="is_route" label="是否是路由" label-col-flex="100px">
              <a-radio-group v-model="formModel.is_route">
                <a-radio :value="1">是</a-radio>
                <a-radio :value="0">否</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item field="type" label="类型" label-col-flex="100px">
              <a-radio-group v-model="formModel.type">
                <a-radio v-for="(item, index) in stateObj.types" :key="index" :value="stateObj.types[index].value">{{ stateObj.types[index].label }}</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item field="icon" label="图标" label-col-flex="100px">
              <a-input-group>
                <a-input v-model="formModel.icon" placeholder="" style="width: 80%">
                  <template #suffix>
                    <component v-if="formModel.icon" :is="formModel.icon"></component>
                  </template>
                </a-input>
                <a-button type="text" @click="iconDialogVisible = true">选择</a-button>
              </a-input-group>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="sort" label="排序" label-col-flex="100px">
              <a-input-number v-model="formModel.sorting" mode="button" :style="{width:'160px'}"/>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="status" label="是否启用" label-col-flex="100px">
              <a-switch v-model="formModel.status" :checked-value="1" :unchecked-value="2"/>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-modal>

    <a-modal
      v-model:visible="iconDialogVisible"
      :title="iconDialogTitle"
      :modal-style="{ width: '60%', height: '80%' }"
      :mask-closable="false"
    >
      <icon-manage @cancelCallback="iconCancel" @okCallback="iconOk" />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref } from 'vue';
  import { FormInstance } from '@arco-design/web-vue/es/form';

  import { disabledTree } from '@/utils';
  import { apiInfo, apiSave } from '@/api/menu';
  import IconManage from '@/components/icon/index.vue';

  const props = defineProps({
    visible: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: '',
    },
    id: {
      type: [Number, String],
      default: '',
    },
    treeDatas: {
      type: Array,
      default() {
        return [];
      },
    },
  });
  const emit = defineEmits(['saveCallback']);

  const baseFormModel = () => {
    return {
      id: '',
      created_at: '',
      updated_at: '',
      parent_id: '',
      name: '',
      app: '',
      controller: '',
      action: '',
      route: '',
      is_route: 1,
      type: 1,
      icon: '',
      sorting: 100,
      status: 1,
    };
  };
  const formRef = ref<FormInstance>();
  const baseTreeDatas = () => {
    return JSON.parse(JSON.stringify(props.treeDatas));
  };
  // const treeDatas = ref<any[]>(props.treeDatas);
  const treeDatas = ref<any[]>();
  const formModel = ref<any>(baseFormModel());
  const modalStyle = {
    width: '50%',
    height: '60%',
  };
  const bodyStyle = {
    height: 'calc(100% - 108px)',
    overflow: 'auto',
  };

  // const dialogVisible = ref(props.visible);
  const dialogVisible = ref(false);
  const dialogTitle = ref();
  const btnLoading = ref(false);
  const iconDialogVisible = ref(false);
  const iconDialogTitle = ref('图标管理');

  const stateObj: any = {
    types: [
      {value: 1, label: '模块'},
      {value: 2, label: '列表'},
      {value: 3, label: '操作'},
    ],
  };

  // 表单重置
  const reset = async () => {
    formModel.value = baseFormModel();
    await formRef.value?.resetFields();
    treeDatas.value = baseTreeDatas();
  };
  const fetchData = async (row?: any, type?: string) => {
    // treeDatas.value = props.treeDatas;
    treeDatas.value = baseTreeDatas();

    dialogVisible.value = true;
    dialogTitle.value = '新增';
    if (row && type === 'edit') {
      dialogTitle.value = `编辑: ${row.id}`;
    }
    reset();
    if (row && row.id) {
      if (type === 'edit') {
        // 编辑
        const { data } = await apiInfo({id: row.id});
        formModel.value = data;
        if (formModel.value.parent_id === 0) {
          formModel.value.parent_id = '';
        }
        treeDatas.value = disabledTree(treeDatas.value, row.id);
      } else {
        // 添加子集
        formModel.value.parent_id = row.id;
      }
    }
  };
  // 提交
  const submit = async (done: any) => {
    btnLoading.value = true;
    try {
      const ruleRes = await formRef.value?.validate();
      if (!ruleRes) {
        await apiSave(formModel.value);
        done();
        emit('saveCallback');
      } else {
        done(false);
      }
    } catch (err) {
      done(false);
      btnLoading.value = false;
    } finally {
      done(false);
      btnLoading.value = false;
    }
  };

  // 图标回调
  const iconCancel = () => {
    iconDialogVisible.value = false;
  };
  const iconOk = (icon: string) => {
    iconDialogVisible.value = false;
    formModel.value.icon = icon;
  };

  const dialogCancel = () => {
    dialogVisible.value = false;
    reset();
  };
  const dialogBeforeOk = (done: any) => {
    submit(done);
  };

  // 暴露方法【给父级调用】
  defineExpose({
    fetchData,
  });
</script>

<style scoped lang="less">
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
